function compose() {
  const func = [...arguments];

  return function (...args) {
    return func.reduce((prev, cur) => {
      return cur && cur(prev);
    }, ...args);
  };
}

const add = (arr) => arr.map((item) => item + 2);
const sub = (a) => a - 1;
const mul = (a) => a ** 3;
const multiply = function (num) {
  return function (arr) {
    return arr.map((item) => item * num);
  };
};

const multiply2 = multiply(2);

// const newMethod = compose(add, sub, mul);

// console.log(newMethod(1));

function composeAsync() {
  const funcs = [...arguments];
  console.log(funcs);
  return function (...args) {
    return funcs.reduce((prev, cur) => {
      return cur(prev);
    }, ...args);
  };
}

const func = composeAsync(multiply2, add);
const res = func([1, 2, 3, 4, 5]);
console.log(res);


function composeV1() {
  const fncs = [...arguments];
  return function (...args) {
    return fncs.reduce((pre, cur) => {
      return cur(pre);
    }, ...args);
  };
}


function composeV2() {
  const fns = [...arguments];
  console.log(fns);

  return function (...args) {
    console.log(...args);
    // return fns.reduce((prev, cur) => cur(prev), ...args);
  };
}

const foo = composeV2(multiply, add);
const resV2 = foo(2);
// console.log(resV2);